/**
 * tigerrad
 * fall 2006
 */

#ifndef _CAMERA_H
#define _CAMERA_H

#include "Util.h"

/**
 * Simple Camera class...
 */
class Camera
{
	public:
		/**
		 * Constructor.  Sets values to default OpenGL camera.
		 */
		Camera() : _pos(Vec3(0,0,0)), _dir(0,0,-1), _up(0,1,0), _fovy(45.0), 
				   _near(0.1), _far(100.0), _size(Vec2s(640, 480))
		{
			Vec3 at = _pos+_dir;
			_view_mat.makeLookAt(_pos, at, _up);
			_proj_mat.makePerspective(_fovy, _size[0]/(float)(_size[1] == 0 ? 1 : _size[1]), _near, _far);
		}

		/**
		 * Constructor.
		 */
		Camera(const Vec3& p, const Vec3& d, const Vec3& u, float fovy, float near, float far, Vec2s size) 
			: _pos(p), _dir(d), _up(u), _fovy(fovy), _near(near), _far(far), _size(size)
			
		{
			Vec3 at = _pos+_dir;
			_view_mat.makeLookAt(_pos, at, _up);
			_proj_mat.makePerspective(_fovy, _size[0]/(float)(_size[1] == 0 ? 1 : _size[1]), _near, _far);
		}

		/** Return the camera position. */
		Vec3 getPos() const { return _pos; }

		/** Return the camera direction. */
		Vec3 getDir() const { return _dir; }

		/** Return the camera up direction. */
		Vec3 getUp() const { return _up; }

		/** Return a point the camera is looking at. */
		Vec3 getAt() const { return _pos + _dir; }

		/** Return the field of view in the y direction. */
		float getFovy() const { return _fovy; }

		/** Return the near plane. */
		float getNear() const { return _near; }
		
		/** Return the far plane. */
		float getFar() const { return _far; }

		/** Return the size */
		Vec2s getSize() const { return _size; }

		/** Calc. and return the aspect ratio (width/height) */
		float getAspectRatio() const { return _size[0] / (float)(_size[1] == 0 ? 1 : _size[1]); }

		/**
		 * Return the view matrix of the camera.
		 */
		const Matrix& getViewMatrix() const { return _view_mat; }

		/**
		 * Return the projection matrix of the camera.
		 */
		const Matrix& getProjMatrix() const { return _proj_mat; }

	private:
		Vec3 _pos;
		Vec3 _dir;
		Vec3 _up;
		float _fovy;
		float _near;
		float _far;
		Vec2s _size;

		/** The heart of the Camera for now...*/
		Matrix _view_mat;
		Matrix _proj_mat;

		bool _viewDirty;
		bool _projDirty;
};

#endif

